import interceptor from './router.interceptor';
import queryParams from '@/utils/queryParams';
import {ROUTE_TYPE} from '@/enum/router';

const tabbarList : string[] = [
	'/pages/home/home',
	'/pages/statistics/statistics',
	'/pages/device/device',
	'/pages/mine/mine',
	'/pages/share/share'
]

declare interface IRouter {
	tabbarList : string[];
	routerMethods : string[];
	config : IRouteConfig;
	route(options : string | IRouteConfig) : void;
	getPages() : Page.PageInstance<AnyObject, {}>[];
	back() : void;
	interceptorInit() : void;
}





declare interface IRouteConfig {
	type ?: ROUTE_TYPE,
	url : string,
	params ?: AnyObject,
	success ?: (result ?: any) => void,
	fail ?: (err ?: any) => void,
}

interface NavigateToSuccessOptions {
	/**
	 * 回调信息
	 */
	errMsg : string;
	/**
	 * 和被打开页面进行通信
	 */
	eventChannel : EventChannel;
	url ?: string;
}

interface EventChannel {
	/**
	 * 触发一个事件
	 */
	emit(eventName : string, args ?: any[]) : void;
	/**
	 * 持续监听一个事件
	 */
	on(eventName : string, fn ?: (result : any) => void) : void;
	/**
	 * 取消监听一个事件。给出第二个参数时，只取消给出的监听函数，否则取消所有监听函数
	 */
	off(eventName : string, fn ?: (result : any) => void) : void;
	/**
	 * 监听一个事件一次，触发后失效
	 */
	once(eventName : string, fn ?: (result : any) => void) : void;
}


class Router implements IRouter {
	config : IRouteConfig = {
		type: ROUTE_TYPE.NAVIGATETO,
		url: '',
		params: {},
		success: () => {

		},
		fail: () => {

		}
	}
	tabbarList : string[] = [];
	routerMethods : string[] = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab', 'navigateBack'];
	constructor(tabbarList : string[]) {
		console.log(tabbarList)
		this.tabbarList = tabbarList;
		console.log(this.tabbarList)
	}
	route = (options : string | IRouteConfig) => {
		if (typeof options === 'string') {
			const route_type = this.tabbarList.indexOf(options.split('?')[0]) !== -1 ? ROUTE_TYPE.SWITCHTAB : ROUTE_TYPE.NAVIGATETO;
			let cloneConfig : IRouteConfig = JSON.parse(JSON.stringify(this.config));
			cloneConfig.type = route_type;
			this.openPage(options, cloneConfig);
		} else {
			const mergeConfig = Object.assign(this.config, options);
			const query = queryParams(options.params);
			options.url += query;
			this.openPage(options.url, mergeConfig);
		}
	}
	openPage = (url : string, config : IRouteConfig) => {

		switch (config.type) {
			case ROUTE_TYPE.NAVIGATETO:
				uni.navigateTo({
					url,
					success: config.success,
					fail: config.fail,
				})
				break;
			case ROUTE_TYPE.REDIRECTTO:
				uni.redirectTo({
					url,
					success: (res : NavigateToSuccessOptions) => {
						res.url = url;
						if (config.success) {
							console.log(config.success)
							config.success(res);
						}
					},
					fail: config.fail,
				})
			case ROUTE_TYPE.SWITCHTAB:
				uni.switchTab({
					url,
					success: (res : NavigateToSuccessOptions) => {
						res.url = url;
						if (config.success) {
							config.success(res);
						}
					},
					fail: config.fail,
				})
			case ROUTE_TYPE.RELAUNCH:
				uni.reLaunch({
					url,
					success: (res : NavigateToSuccessOptions) => {
						res.url = url;
						if (config.success) {
							config.success(res);
						}
					},
					fail: config.fail,
				})
			default:
				uni.navigateTo({
					url,
					success: (res : NavigateToSuccessOptions) => {
						res.url = url;
						if (config.success) {
							config.success(res);
						}
					},
					fail: config.fail,
				})
				break;
		}
	}
	back() {
		uni.navigateBack()
	}
	getPages() {
		return getCurrentPages()
	}
	interceptorInit = () => {
		this.routerMethods.forEach((item : string) => {
			uni.addInterceptor(item, {
				invoke(route) {
					return interceptor.beforeEach(route)
				},
				success(result) {
					return interceptor.afterEach(result)
				}
			})
		})
	}
}

export default new Router(tabbarList);

export type {
	ROUTE_TYPE
}